package com.spring.cloud.weatherbasic.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.cloud.weatherbasic.service.WeatherDataService;
import com.spring.cloud.weatherbasic.vo.WeatherResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2018/3/13
 */
@Slf4j
@Service
public class WeatherDataServiceImpl implements WeatherDataService {

    private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?";

    private static final long TIME_OUT = 30 * 60L;

    private static final String REDIS_NAMESPACE_WEATHER = "weather:";

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 根据城市ID查询天气数据
     *
     * @param cityId cityId
     * @return WeatherResponse
     */
    @Override
    public WeatherResponse getDataByCityId(String cityId) {
        String uri = WEATHER_URI + "citykey=" + cityId;
        return this.doGetWeather(uri);
    }

    /**
     * 根据城市名称查询天气数据
     *
     * @param cityName cityName
     * @return WeatherResponse
     */
    @Override
    public WeatherResponse getDataByCityName(String cityName) {
        String uri = WEATHER_URI + "city=" + cityName;
        return this.doGetWeather(uri);
    }

    /**
     * 根据城市ID来同步天气
     *
     * @param cityId cityId
     */
    @Override
    public void syncDataByCityId(String cityId) {
        String uri = WEATHER_URI + "citykey=" + cityId;
        this.getWeatherDataAndSaveToRedis(uri);
    }

    /**
     * 把天气数据放在缓存
     * @param uri uri
     */
    private String getWeatherDataAndSaveToRedis(String uri) {
        String key = REDIS_NAMESPACE_WEATHER + uri;
        String strBody = null;
        ValueOperations<String, String>  ops = redisTemplate.opsForValue();

        // 调用服务接口来获取
        ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);

        if (respString.getStatusCodeValue() == 200) {
            strBody = respString.getBody();
        }

        // 数据写入缓存
        if (strBody != null) ops.set(key, strBody, TIME_OUT, TimeUnit.SECONDS);

        return strBody;
    }

    private WeatherResponse doGetWeather(String uri) {
        String key = REDIS_NAMESPACE_WEATHER + uri;
        String strBody = null;
        WeatherResponse resp = null;
        ObjectMapper mapper = new ObjectMapper();
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        // 先查缓存，缓存有的取缓存中的数据
        if (redisTemplate.hasKey(key)) {
            log.info("Redis has data");
            strBody = ops.get(key);
        } else {
            log.info("Redis don't has data");
            strBody = getWeatherDataAndSaveToRedis(uri);
        }

        try {
            resp = mapper.readValue(strBody, WeatherResponse.class);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("Error!", e);
        }

		return resp;
	}

}
